import random
from PIL import Image, ImageDraw, ImageFont
import io


class Captcha:
    def __init__(self, width=120, height=40, length=4):
        self.width = width
        self.height = height
        self.length = length
        self.font = ImageFont.load_default()  # 使用默认字体，可替换为自定义字体
        self.chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'  # 排除易混淆字符

    def generate_code(self):
        """生成随机验证码字符串"""
        return ''.join(random.sample(self.chars, self.length))

    def generate_image(self, code):
        """生成验证码图片"""
        # 创建画布
        image = Image.new('RGB', (self.width, self.height), self._get_random_color(200, 250))
        draw = ImageDraw.Draw(image)

        # 添加噪点
        self._add_noise(draw)

        # 添加干扰线
        self._add_lines(draw)

        # 绘制验证码字符
        for i, char in enumerate(code):
            draw.text(
                (10 + i * (self.width - 20) / self.length, 10),
                char,
                font=self.font,
                fill=self._get_random_color(10, 100)
            )

        return image

    def _get_random_color(self, min_val, max_val):
        """生成随机颜色"""
        return (
            random.randint(min_val, max_val),
            random.randint(min_val, max_val),
            random.randint(min_val, max_val)
        )

    def _add_noise(self, draw):
        """添加噪点"""
        for _ in range(random.randint(100, 200)):
            draw.point(
                (random.randint(0, self.width), random.randint(0, self.height)),
                fill=self._get_random_color(60, 120)
            )

    def _add_lines(self, draw):
        """添加干扰线"""
        for _ in range(random.randint(2, 4)):
            x1 = random.randint(0, self.width)
            y1 = random.randint(0, self.height)
            x2 = random.randint(0, self.width)
            y2 = random.randint(0, self.height)
            draw.line(
                [(x1, y1), (x2, y2)],
                fill=self._get_random_color(80, 180),
                width=1
            )

    def get_captcha(self):
        """获取验证码和图片二进制数据"""
        code = self.generate_code()
        image = self.generate_image(code)

        # 将图片转换为二进制流
        buffer = io.BytesIO()
        image.save(buffer, 'PNG')
        buffer.seek(0)

        return code, buffer

cap=Captcha()